home *** CD-ROM | disk | FTP | other *** search
- #ifdef __STDC__
- static char sccs_id[] = "@(#) strtod.c 1.3 "__DATE__" HJR";
- #else
- static char sccs_id[] = "@(#) strtod.c 1.3 26/9/90 HJR";
- #endif
-
- /* strtod.c (c) Copyright 1990 H.Rogers */
-
- #include <ctype.h>
- #ifdef __STDC__
- #include <stdlib.h>
- #else
- extern double strtod();
- #endif
-
- #define MAXEXP 308 /* maximum decimal exponential for IEEE double */
-
- /* recognizes: [spaces][sign][digs][[.][digs]][[e|E][space|sign][int]] */
-
- /* this is the most efficient strtod() can be, without resorting to
- * assuming IEEE 'D' or some other floating point representation */
-
- double strtod(register const char *s,char **end)
- {
- register double r,p;
- register unsigned int x;
- register int r_,x_;
- const char *_s;
-
- r = 0; r_ = 0;
-
- if (!s) return(r);
-
- while (isspace(*s++)); s--;
-
- if (*s == '-' || *s == '+')
- {
- if (*s == '-') r_ = 1;
- s++;
- }
-
- while (isdigit(*s))
- {
- r = r * 10 + (*s - '0');
- s++;
- }
-
- if (*s != '.') goto integer;
-
- s++; p = 1; while (isdigit(*s))
- {
- r = r * 10 + (*s - '0');
- p *= 10;
- s++;
- }
- r /= p;
-
- integer: if (!(*s == 'e' || *s == 'E')) goto ret;
-
- x_ = (int)strtol(++s,(char **)&_s,0); s = _s;
-
- x_ = (x_ < 0) ? ((x = (unsigned int)(-x_)),1) : ((x = (unsigned int)x_),0);
-
- if (x > MAXEXP) { r_ = 0; r = 0; goto ret; }
-
- p = 1; while (x) p *= 10,x--; r = (x_) ? (r / p) : (r * p);
-
- ret: if (end) *end = (char *)s;
-
- return(r_ ? -r : r);
- }
-